package vn.com.pavibook.admin.service;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import vn.com.pavibook.dao.BookDao;
import vn.com.pavibook.dao.BookTypeDao;
import vn.com.pavibook.dao.PublisherDao;
import vn.com.pavibook.domain.model.Book;
import vn.com.pavibook.domain.model.BookType;
import vn.com.pavibook.domain.model.PagingInfo;
import vn.com.pavibook.domain.model.SearchResult;
import vn.com.pavibook.model.vo.BookVO;
import vn.com.pavibook.utils.DataHelper;

@Service
public class ManageBookService {
	
	private static final Logger logger = LoggerFactory.getLogger(ManageBookService.class);
	
	@Value("${upload.ebooks.url.server}")
	public String URL_ROOT_FOLDER_UPLOAD_EBOOK;
	
	@Value("${upload.banners.url.server}")
	public String URL_ROOT_FOLDER_UPLOAD_BANNER;
	
	@Value("${upload.ebooks.url.project}")
	public String URL_PROJECT_UPLOAD_EBOOK;

	@Value("${upload.banners.url.project}")
	public String URL_PROJECT_UPLOAD_BANNER;
	
	@Autowired
	private BookTypeDao bookTypeDao;
	
	@Autowired
	private BookDao bookDao;
	
	@Autowired
	private PublisherDao publisherDao;
	
	public Model createNewBook(Model model, BookVO bookVO){
		logger.debug("service createNewBook");
		List<BookType> bookTypeList = bookTypeDao.getAllBookType();
		if(bookVO != null){
			if(bookVO.getId() == 0){
				model.addAttribute("pdfCurrent", "");
				model.addAttribute("imageCurrent", "");
			}else{
				String pdfCurrent = bookVO.getUrlPdfFile().substring(bookVO.getUrlPdfFile().lastIndexOf("/") + 1);
				String imageCurrent = bookVO.getUrlImageFile().substring(bookVO.getUrlImageFile().lastIndexOf("/") + 1);
				model.addAttribute("pdfCurrent", pdfCurrent);
				model.addAttribute("imageCurrent", imageCurrent);
			}
		}
		model.addAttribute("bookTypeList", bookTypeList);
		return model;
	}
	
	@SuppressWarnings("deprecation")
	public boolean uploadFileBook(Model model, BookVO bookVO, HttpServletRequest request, boolean isEdit){
		logger.debug("service saveBook");
		
		//get username
		SecurityContext context = SecurityContextHolder.getContext();
		String username = context.getAuthentication().getName();
		int publishId = publisherDao.getIdByUsername(username);
		bookVO.setPublisherId(publishId);
		
		//get root in project
		//String urlRootProject = request.getRealPath(DataHelper.FolderImageFileUploadInProject.EBOOK_IMAGE.getCode()) ;
		String urlRootProject = request.getRealPath(URL_PROJECT_UPLOAD_EBOOK) ;
		
		//upload file
		CommonsMultipartFile imageFileUpload = bookVO.getImageFileUpload();
		CommonsMultipartFile pdfFileUpload = bookVO.getPdfFileUpload();
		//String rootUrl = DataHelper.UrlRootFolderUpload.URL_ROOT_FOLDER_UPLOAD_EBOOK.getCode();
		String rootUrl = URL_ROOT_FOLDER_UPLOAD_EBOOK;
		Date dateCurrentImage = new Date();
		long dateCurrentTimeImage = dateCurrentImage.getTime();
		if(!isEdit){
			bookVO.setCreateDate(dateCurrentImage);
		}
		
		//url image file
		String urlFileImageFull = rootUrl;
		String urlFileImageFullInProject = urlRootProject;
		
		//upload image file
		boolean hasErrorUploadImage = true;
		if (imageFileUpload == null || imageFileUpload.getSize() <= 0) {
			if(isEdit){
				hasErrorUploadImage = false;
			}else{
				hasErrorUploadImage = true;
				model.addAttribute("errorUploadImage", DataHelper.UploadFileStatus.UPLOAD_EMPTY.getCode());
			}
		} else {
			if(StringUtils.isEmpty(bookVO.getUrlImageFile())){
				String urlFileImage = "/" + username + "/ebook_" + dateCurrentTimeImage + "/image_" + dateCurrentTimeImage +"/" + imageFileUpload.getOriginalFilename();
				urlFileImageFull = rootUrl + urlFileImage;
				urlFileImageFullInProject = urlFileImageFullInProject + urlFileImage;
				bookVO.setUrlImageFile(urlFileImage);
			}else{
				String urlFileImage = bookVO.getUrlImageFile().substring(0, bookVO.getUrlImageFile().lastIndexOf("/") + 1) + imageFileUpload.getOriginalFilename();
				urlFileImageFull = rootUrl + urlFileImage;
				urlFileImageFullInProject = urlFileImageFullInProject + urlFileImage;
				bookVO.setUrlImageFile(urlFileImage);
			}
			
			String fileTypeImageList = DataHelper.ImageFile.IMAGE_FILE_TYPE.getCode();
			String maxSizeImageStr = DataHelper.ImageFile.IMAGE_FILE_MAX_LENGTH.getCode();
			long maxSizeImage = Long.parseLong(maxSizeImageStr);
			
			String resultUploadFileImage = uploadSingleFile(imageFileUpload, urlFileImageFull, maxSizeImage, fileTypeImageList);
			logger.debug("upload Image result : " + resultUploadFileImage);
			
			if (DataHelper.ResultUpload.RESULT_UPLOAD_SUCCESS.getCode().equals(resultUploadFileImage)) {
				
				hasErrorUploadImage = false;
				model.addAttribute("errorUploadImage", DataHelper.UploadFileStatus.UPLOAD_SUCCESS.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_ERROR.getCode().equals(resultUploadFileImage)){
				model.addAttribute("errorUploadImage", DataHelper.UploadFileStatus.UPLOAD_FILE_ERROR.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_INCORRECT.getCode().equals(resultUploadFileImage)){
				model.addAttribute("errorUploadImage", DataHelper.UploadFileStatus.UPLOAD_FILE_FAILURE_FORMAT.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_LIMIT.getCode().equals(resultUploadFileImage)){
				model.addAttribute("errorUploadImage", DataHelper.UploadFileStatus.UPLOAD_FILE_LIMIT.getCode());
			}
		}
		
		//url pdf file
		Date dateCurrentPdf = new Date();
		long dateCurrentTimePdf = dateCurrentPdf.getTime();
		
		String urlFilePdfFull = rootUrl;
		
		//upload pdf file
		boolean hasErrorUploadPdf = true;
		if (pdfFileUpload == null || pdfFileUpload.getSize() <= 0) {
			if(isEdit){
				hasErrorUploadPdf = false;
			}else{
				hasErrorUploadPdf = true;
				model.addAttribute("errorUploadPdf", DataHelper.UploadFileStatus.UPLOAD_EMPTY.getCode());
			}
		} else {
			if(StringUtils.isEmpty(bookVO.getUrlPdfFile())){
				String urlFilePdf = "/" + username + "/ebook_" + dateCurrentTimeImage + "/pdf_"+ dateCurrentTimePdf +"/" + pdfFileUpload.getOriginalFilename();
				urlFilePdfFull = rootUrl + urlFilePdf;
				bookVO.setUrlPdfFile(urlFilePdf);
			}else{
				String urlFilePdf = bookVO.getUrlPdfFile().substring(0, bookVO.getUrlPdfFile().lastIndexOf("/") + 1) + pdfFileUpload.getOriginalFilename();
				urlFilePdfFull = rootUrl + urlFilePdf;
				bookVO.setUrlPdfFile(urlFilePdf);
			}
			
			String fileTypePdfList = DataHelper.PdfFile.PDF_FILE_TYPE.getCode() + ", " + DataHelper.PdfFile.EPUB_FILE_TYPE.getCode();
			//String maxSizeImageStr = DataHelper.ImageFile.IMAGE_FILE_MAX_LENGTH.getCode();
			long maxSizePdf = 0;
			
			String resultUploadFilePdf = uploadSingleFile(pdfFileUpload, urlFilePdfFull, maxSizePdf, fileTypePdfList);
			logger.debug("upload Image result : " + resultUploadFilePdf);
			
			if (DataHelper.ResultUpload.RESULT_UPLOAD_SUCCESS.getCode().equals(resultUploadFilePdf)) {
				hasErrorUploadPdf = false;
				model.addAttribute("errorUploadPdf", DataHelper.UploadFileStatus.UPLOAD_SUCCESS.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_ERROR.getCode().equals(resultUploadFilePdf)){
				model.addAttribute("errorUploadPdf", DataHelper.UploadFileStatus.UPLOAD_FILE_ERROR.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_INCORRECT.getCode().equals(resultUploadFilePdf)){
				model.addAttribute("errorUploadPdf", DataHelper.UploadFileStatus.UPLOAD_FILE_FAILURE_FORMAT.getCode());
			} else if(DataHelper.ResultUpload.RESULT_UPLOAD_LIMIT.getCode().equals(resultUploadFilePdf)){
				model.addAttribute("errorUploadPdf", DataHelper.UploadFileStatus.UPLOAD_FILE_LIMIT.getCode());
			}
		}
		
		model.addAttribute("hasErrorUploadPdf", hasErrorUploadPdf);
		model.addAttribute("hasErrorUploadImage", hasErrorUploadImage);
		if(!hasErrorUploadPdf && !hasErrorUploadImage){
			return true;
		}else{
			return false;
		}
	}
	
	public void saveBook(BookVO bookVO, boolean isEdit){
		Book book = convertToBook(bookVO);
		if(!isEdit){
			bookDao.addNewBook(book);
		}else{
			bookDao.editBook(book);
		}
	}
	
	
	//get detail
	public BookVO getBookDetail(int bookId){
		BookVO bookVO = new BookVO();
		Book book = bookDao.getBookById(bookId);
		bookVO = convertToBookVO(book);
		return bookVO;
	} 
	
	//get delete
	public void deleteBook(int bookId){
		bookDao.deleteBook(bookId);
	} 
	
	public Book convertToBook(BookVO bookVO){
		Book book = new Book();
		book.setActive(bookVO.getActive());
		book.setAuthor(bookVO.getAuthor());
		book.setBookTypeId(bookVO.getBookTypeId());
		book.setCreateDate(bookVO.getCreateDate());
		
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
		Date date = null;
		try {
			date = simpleDateFormat.parse(bookVO.getDatePublish());
			book.setDatePublish(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		book.setDiscount(bookVO.getDiscount());
		book.setId(bookVO.getId());
		book.setIsHot(bookVO.getIsHot());
		book.setLikeNumber(bookVO.getLikeNumber());
		book.setName(bookVO.getName());
		book.setNumberRepublish(bookVO.getNumberRepublish());
		book.setPrice(bookVO.getPrice());
		book.setPublisherId(bookVO.getPublisherId());
		book.setShortDescription(bookVO.getShortDescription());
		book.setLongDescription(bookVO.getLongDescription());
		book.setStatus(StringUtils.EMPTY);
		book.setTitle(bookVO.getTitle());
		book.setUrlImageFile(bookVO.getUrlImageFile());
		book.setUrlPdfFile(bookVO.getUrlPdfFile());
		return book;
	}
	
	public BookVO convertToBookVO(Book book){
		BookVO bookVO = new BookVO();
		bookVO.setActive(book.getActive());
		bookVO.setAuthor(book.getAuthor());
		bookVO.setBookTypeId(book.getBookTypeId());
		bookVO.setCreateDate(book.getCreateDate());
		
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
		Date date = book.getDatePublish();
		try {
			String dataVO = simpleDateFormat.format(date);
			bookVO.setDatePublish(dataVO);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		bookVO.setDiscount(book.getDiscount());
		bookVO.setId(book.getId());
		bookVO.setIsHot(book.getIsHot());
		bookVO.setLikeNumber(book.getLikeNumber());
		bookVO.setLongDescription(book.getLongDescription());
		bookVO.setName(book.getName());
		bookVO.setNumberRepublish(book.getNumberRepublish());
		bookVO.setPrice(book.getPrice());
		bookVO.setPublisherId(book.getPublisherId());
		bookVO.setShortDescription(book.getTitle());
		bookVO.setStatus(StringUtils.EMPTY);
		bookVO.setTitle(book.getTitle());
		bookVO.setUrlImageFile(book.getUrlImageFile());
		bookVO.setUrlPdfFile(book.getUrlPdfFile());
		
		return bookVO;
	}
	
	public SearchResult<Book> getListBookByUsername(String username, PagingInfo pagingInfo,
			String keyword, String typeSearch){
		int publisherId = publisherDao.getIdByUsername(username);
		
		return bookDao.getBooks(pagingInfo, keyword, typeSearch, publisherId);
	}
	
	public String uploadSingleFile(CommonsMultipartFile filea, String fullPathFileName, long maxSize,String fileTypeList){
		boolean testType = false;
		if(fileTypeList != null){
			
			//check file type
			String [] fileTypeArray = fileTypeList.replace(" ", "").split(",");
			String filename = null;
			String fileTypeCurrent = null;
			try{
				filename = filea.getOriginalFilename();
				fileTypeCurrent = filename.substring(filename.lastIndexOf(".")+1);
			}catch (Exception e) {
				e.printStackTrace();
				return DataHelper.ResultUpload.RESULT_UPLOAD_INCORRECT.getCode();
			}
			
			if(fileTypeArray.length > 0){
				for(int i = 0; i < fileTypeArray.length; i++){
					if(fileTypeArray[i].toLowerCase().equalsIgnoreCase(fileTypeCurrent)){
						testType = true;
					};
				}
			}
		}else{
			testType = true;
		}
		if(testType){
			if (filea.getSize() > 0 && (filea.getSize() <= maxSize || maxSize == 0)) {
				try {
					File file = new File(fullPathFileName);
					file.mkdirs();
					filea.transferTo(file);
				} catch (Exception e) {
					e.printStackTrace();
					return DataHelper.ResultUpload.RESULT_UPLOAD_ERROR.getCode();
				}
				return DataHelper.ResultUpload.RESULT_UPLOAD_SUCCESS.getCode();
			} else {
				return DataHelper.ResultUpload.RESULT_UPLOAD_LIMIT.getCode();
			}
		}else{
			return DataHelper.ResultUpload.RESULT_UPLOAD_INCORRECT.getCode();
		}
	}
	
	public String getNamePublishByUsername(String username){
		return publisherDao.getNameByUsername(username);
	}
	
	public String getNameBookTypeById(int bookTypeId){
		BookType bookType = bookTypeDao.getBookTypeById(bookTypeId);
		if(bookType == null){
			return "";
		}
		return bookType.getName();
	}
	
	public void copyFile(String fromFile, String toFile){
		try{
			File input = new File(fromFile);
			File output = new File(toFile);
			//output.mkdir();
			FileUtils.copyFile(input, output); 
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public SearchResult<Book> getTop10BookOfTransaction(String role, String username){
		int publisherId = 0;
		if(DataHelper.UserRole.ROLE_PUBLISHER.getCode().equals(role)){
			publisherId = publisherDao.getIdByUsername(username);
		}else if(DataHelper.UserRole.ROLE_FOR_ADMIN.getCode().equals(role)){
			publisherId = 0;
		}else{
			return new SearchResult<Book>();
		}
		
		return bookDao.getTop10BookOfTransaction(role, publisherId);
	}
}
